\documentclass{article}

\usepackage{xeCJK}
\setmainfont{Arial}
\setCJKmainfont{Microsoft YaHei}

\usepackage{listings}
\lstset{language=Java}
\newcommand{\code}[1]{\mbox{\lstinline|#1|}}

\title{异常处理代码的可信自动测试}
\date{}

\begin{document}
\maketitle

异常机制是现代面向对象语言中重要的元素，异常处理代码的正确性对整个软件的正确性有重要影响。
然而，与程序中的其他代码相比，异常处理代码本身更容易包含错误，也更难以测试\cite{}。
基于程序插装的异常处理代码测试技术通过在程序中插入语句来主动触发异常，进而测试相应的异常处理代码\cite{}。
一方面，这类技术可以实现在程序的任意位置触发各种异常，因而相当灵活；
另一方面，因为程序中可以进行插装的位置通常不唯一，且在不同位置进行插装对程序行为会产生不同的影响，
所以插装后程序的异常处理行为未必能反映原代码的异常处理行为，使得最终测试结果的可信度难以保证。
本项目拟对现有基于程序插装的异常代码测试技术的不足展开研究，并在此基础上设计、实现对异常处理代码的可信自动测试。

项目计划分如下步骤实施：
\begin{enumerate}
    \item 评估不同插装策略对测试可信度的影响；\footnote{这里我们主要考虑不同插装位置对应的不同插装策略}\\
    对同一程序应用不同的插装策略对程序控制流引入不同的变化，插装后的异常处理行为与原始程序的异常处理行为之间的差异决定了测试结果的可信度。
    在这一阶段，我们选择一系列带有测试用例的开源代码，并挑选那些执行过程中触发了异常的测试进行实验。
    实验中，我们对测试所覆盖的代码在不同位置进行插装，监测程序在插装前后的行为，评估插装前后异常处理行为的一致性，并以此为依据衡量插装对测试结果可信度的影响。

    \item 设计算法来自动根据待测异常处理代码选择合适的插装策略；
    \footnote{目前我们估计插装点离异常抛出点越近则得到的测试行为越接近实际行为，尤其是当异常的触发与环境（如I/O）相关时。
    如果这一点从实验结论中可以明显看出，则我们或许可以考虑简化这一步骤。
    但一般来说，分类算法应该可以用于选择最优插装策略。}\\
    总结影响测试可信度的代码静态属性，如处理异常的种类、异常处理代码与其他代码之间的数据依赖等，
    并由此构造分类模型来根据待测异常处理代码的属性指导选择插装策略。
    通过cross validation评估模型的质量。


    \item 开发支撑工具实现对异常的自动可信测试，并针对开源代码进行实验以验证工具的有效性与效率。
    在这一阶段，工具应能实现自动选择最佳策略对软件进行插装，然后自动执行测试，并报告异常结束的测试。
    
    工具的有效性取决于异常结束的测试是否反映真实的代码缺陷；而工具的效率由结果中false positive的比例决定。
    为了评价测试结果的质量，我们需要手工对（一部分）异常结束的测试进行分析，看它们是否对应于代码缺陷。
\end{enumerate}

\paragraph{插装前后代码异常处理行为的一致性}
考虑图\ref{fig:example}中的3个方法\code{f}、\code{g}、\code{h}和一个测试\code{T}：在\code{T}执行过程中调用了方法\code{f}，\code{f}调用了\code{g}，而\code{g}又调用了\code{h}，
且\code{T}执行时在(3)处触发了异常。
现有的异常插入技术\cite{FHF05}通过在(1)和(2)处分别插入异常抛出语句\code{throw new E1();}并重新执行\code{T}来测试\code{f}中的异常处理代码。
为了评估插装位置对异常的处理以至于程序的后续执行所产生的影响，我们分别在位置(1)和(2)处插入\code{throw new E1();}，得到原始代码的2个变形（mutant）；
执行原始代码及其变形，我们可以得到三种（可能互异的）异常处理行为。

考虑原始代码的异常处理行为B和其变形对应的异常处理行为B',
我们可以采取不同的B'和B之间一致性的定义
\footnote{从讨论的完整性考虑，此处也列出了白盒一致性。但似乎白盒一致性难以在最终的自动测试工具中使用，所以本工作的重点还是在黑盒一致性上。}：
从黑盒测试角度出发，B和B'是结果一致的当且仅当两者的测试结果相当，即两者均正常结束或以同类型的异常结束。
从白盒测试角度出发，B和B'是语句一致的当且仅当异常处理代码执行完后，两者执行同样的语句序列；
而我们说B和B'是状态一致的当且仅当异常处理代码执行完时，两者的有效程序状态相同\footnote{这里有效程序状态泛指程序仍然可以引用的对象及变量的状态。}。
\underline{只有当插装得到的B'和B一致时，我们才说插装产生的测试是可信的。}\\


\begin{figure}[htb]
\begin{lstlisting}[basicstyle=\footnotesize,numbers=none,numberstyle=\tiny,escapeinside={(*}{*)}]
f(){
   ...
   try{
      ...
      g();                        // (1)
      ...
   }catch(E1 e){
      ...                         // (H)
   }
   ...
}
g() throws E1 {
   ...
   h();                           // (2)
   ...
}
h() throws E1 {
   ...
   if(...) throw new E1();        // (3)
   ...
}
\end{lstlisting}
\caption{一个简单的异常触发、传播的例子。}
\label{fig:example}
\end{figure}

\footnotesize
\begin{thebibliography}{99}

\bibitem{FHF05} Fetzer C, Högstedt K, Felber P.
    Automatic Testing of Exception Handling Code.
    {\em Testing Commercial-off-the-Shelf Components and Systems}.
    Springer Berlin Heidelberg, 2005: 89-105.

\end{thebibliography}

\end{document} 